package tu.linjiebiao.biao;

import tu.juzheng.GraphKind;
import tu.juzheng.IGraph;
import tu.linjiebiao.node.ArcNode;
import tu.linjiebiao.node.VNode;

import java.util.Scanner;

public class ALGraph implements IGraph{
    public final static int INFINITY = Integer.MAX_VALUE;    
    public GraphKind kind;      //图的种类标志
    public int vexNum, arcNum;       //图的当前顶点数和边数
    public VNode[] vexs;                       //顶点  //顺序表
    //交通图矩阵
    public int[][] jz={{0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
                            {1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0},
                            {1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0},
                            {1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
                            {1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0},
                            {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
                            {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1},
                            {1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0},
                            {1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1},
                            {1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
                            {1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1},
                            {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
                            {1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0},
                            {1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0}  };
    //时间矩阵
    public int[][] jz_time = { { INFINITY, 1, 1, 1, 1, INFINITY, 1, 1, 1, 1, 1, 1, 1, 1 },
                            {1, INFINITY, 1, INFINITY, 1, INFINITY, 1, 1, INFINITY, INFINITY, INFINITY, 1, 1, INFINITY},
                            {1, 1, INFINITY, INFINITY, INFINITY, INFINITY, 1, INFINITY, INFINITY, INFINITY, INFINITY, 1, INFINITY, INFINITY},
                            {1, INFINITY, INFINITY, INFINITY, 1, INFINITY, 1, 1, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY},
                            {1, 1, INFINITY, 1, INFINITY, 0, INFINITY, 1, INFINITY, INFINITY, INFINITY, INFINITY, 1, INFINITY},
                            {INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 1, 1, 1, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY},
                            {1, 1, 1, 1, 1, 1, INFINITY, INFINITY, 1, 1, 1, 1, 1, 1},
                            {1, 1, INFINITY, 1, 1, 1, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 1, 1, INFINITY},
                            {1, INFINITY, INFINITY, INFINITY, INFINITY, 1, 1, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 1, 1},
                            {1, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 1, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY},
                            {1, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 1, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 1},
                            {1, 1, 1, INFINITY, INFINITY, INFINITY, 1, 1, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY},
                            {1, 1, INFINITY, INFINITY, 1, INFINITY, 1, 1, 1, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY},
                            {1, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, 1, INFINITY, 1, INFINITY, 1, INFINITY, INFINITY, INFINITY}
                        };
    //金钱矩阵
    public int[][] jz_money={{0, 10, 20, 30, 40, 0, 50, 55, 40, 30, 20, 10, 1, 0},
                            {10, 0, 20, 0, 30, 0, 25, 23, 0, 0, 0, 19, 35, 0},
                            {20, 20, 0, 0, 0, 0, 50, 0, 0, 0, 0, 40, 0, 0},
                            {30, 0, 0, 0, 10, 0, 10, 10, 0, 0, 0, 0, 0, 0},
                            {40, 30, 0, 10, 0, 0, 10, 10, 0, 0, 0, 0, 10, 0},
                            {0, 0, 0, 0, 0, 0, 10, 10, 10, 0, 0, 0, 0, 0},
                            {50, 25, 50, 10, 10, 10, 0, 0, 10, 10, 10, 10, 10, 10},
                            {55, 23, 0, 10, 10, 10, 0, 0, 0, 0, 0, 10, 10, 0},
                            {40, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 10, 10},
                            {30, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0},
                            {20, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 10},
                            {10, 19, 40, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0},
                            {1, 35, 0, 0, 10, 0, 10, 10, 10, 0, 0, 0, 0, 0},
                            {0, 0, 0, 0, 0, 0, 10, 0, 10, 0, 10, 0, 0, 0}  };

    // public int[] cityTime = {1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1}; 

    public ALGraph( Object[] temp){
        this(GraphKind.DN, 14, 39, null);
        //容量
        vexs= new VNode[vexNum];
        for (int i = 0; i < vexNum; i++) {
            vexs[i] = new VNode(temp[i]);
        }
        for (int i = 0; i < jz_time.length; i++) {
            for (int j = 0; j < jz_time[i].length; j++) {
                if(jz_time[i][j] == 1){
                    int v = locateVex(temp[i]);       //弧尾
                    int u = locateVex(temp[j]);       //弧头
                    int value = jz_money[i][j];       //在构建矩阵同时将权值写进去，即不用再赋予一次权值
                    Boolean traffic = true;           //所有地点都有飞机和火车
                    int time = jz_time[i][j];         //小钱钱
                    addArc(v, u, value, traffic, time);
                    addArc(u, v, value, traffic, time);
                }
            }
        }
    }

    public ALGraph(GraphKind kind, int vexNum, int arcNum, VNode[] vexs){
        this.kind = kind;
        this.vexNum = vexNum;
        this.arcNum = arcNum;
        this.vexs = vexs;
    } 

    //创建图
    @Override
    public void createGraph() {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入图的类型:");
        GraphKind kind = GraphKind.valueOf(sc.next());
        switch(kind){
            case UDG:
                createUDG();        //无向图
                return;
            case DG:
                createDG();         //有向图
                return;
            case UDN:
                createUDN();        //无向网
                return;
            case DN:
                createDN();         //有向网
                return;
        }
    }

    //有向图
    private void createDG() {

    };

    //无向图
    private void createUDG() {
    };

    //无向网
    private void createUDN() {
        // Scanner sc = new Scanner(System.in);
        // System.out.println("请分别输入图的顶点数、图的边数：");
        // vexNum = sc.nextInt();
        // arcNum = sc.nextInt();
        // vexs = new VNode[vexNum];
        // System.out.println("请分别输入图的各个顶点：");
        // for (int v = 0; v < vexNum; v++){          //构造顶点向量
        //     vexs[v] = new VNode(sc.next());
        // }
        // System.out.println("请输入各个边的两个顶点及其权值：");
        // for (int k = 0; k < arcNum; k++) {
        //     int v = locateVex(sc.next());       //弧尾
        //     int u = locateVex(sc.next());       //弧头
        //     int value = sc.nextInt();
        //     addArc(v, u, value);
        //     addArc(u, v, value);
        // }
        // for (int i = 0; i < jz.length; i++) {
        //     for (int j = 0; j < jz[i].length; j++) {
        //         if(jz[i][j] == 1){
                    
        //         }
        //     }
        // }
    }

    // //有向网
    private void createDN() {
    //     Scanner sc = new Scanner(System.in);
    //     System.out.println("请分别输入图的顶点数、图的边数：");
    //     vexNum = sc.nextInt();
    //     arcNum = sc.nextInt();
    //     vexs = new VNode[vexNum];
    //     System.out.println("请分别输入图的各个顶点：");
    //     for (int v = 0; v < vexNum; v++){          //构造顶点向量
    //         vexs[v] = new VNode(sc.next());
    //     }
    //     System.out.println("请输入各个边的两个顶点及其权值：");
    //     for (int k = 0; k < arcNum; k++) {
    //         int v = locateVex(sc.next());           //弧头
    //         int u = locateVex(sc.next());           //弧尾
    //         int value = sc.nextInt();
    //         addArc(v, u, value);
    //     }
    }

    //在位置为v、u的顶点之间，添加一条弧，其权值为value
    public void addArc(int v, int u, int value,Boolean traffic, int time) {
        ArcNode arc = new ArcNode(u, value, traffic, time);
        arc.nextArc = vexs[v].firstArc;
        vexs[v].firstArc = arc;
    }
     
    //返回顶点数
    @Override
    public int getVexNum() {
        // TODO Auto-generated method stub
        return vexNum;
    }

    //返回边数
    @Override
    public int getArcNum() {
        // TODO Auto-generated method stub
        return arcNum;
    }

    //返回v表示结点的值，0 ≤ v < vexNum
    @Override
    public Object getVex(int v) throws Exception {
        // TODO Auto-generated method stub
        if(v < 0 && v >= vexNum){
            throw new Exception("第" + v + "个顶点不存在！");
        }
        return vexs[v].data;
    }

    //给定顶点的值vex，返回其在图中的位置，若图中不包含此顶点，则返回-1
    @Override
    public int locateVex(Object vex) {
        // TODO Auto-generated method stub
        for (int v = 0; v < vexNum; v++) {
            if(vexs[v].data.equals(vex)){
                return v;
            }
        }
        return -1;
    }

    public VNode[] getVexs(){
        return vexs;
    }

    public GraphKind getKind(){
        return kind;
    }

    //返回v的第一个邻接表，若v没有邻接点，则返回-1，0 ≤ v < vexNum
    @Override
    public int firstAdjVex(int v) throws Exception {
        // TODO Auto-generated method stub
        if(v < 0 && v >= vexNum){
            throw new Exception("第" + v + "个顶点不存在");
        }
        VNode vex = vexs[v];
        if(vex.firstArc != null){
            return vex.firstArc.adjVex;
        }else{
            return -1;
        }
    }

    //返回v相对于w的下一个邻接点，若w是最后一个邻接点，则返回-1，其中，0 ≤ v < vexNum
    @Override
    public int nextAdjVex(int v, int w) throws Exception {
        // TODO Auto-generated method stub
        if(v < 0 && v >= vexNum){
            throw new Exception("第" + v + "个顶点不存在");
        }
        VNode vex = vexs[v];
        ArcNode arcvw = null;
        for(ArcNode arc = vex.firstArc; arc != null; arc = arc.nextArc){
            if(arc.adjVex == w){
                arcvw = arc;
                break;
            }
        }
        if(arcvw != null && arcvw.nextArc != null){
            return arcvw.nextArc.adjVex;
        }else{
            return -1;
        }
    }
    
}
